﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using bus=WpfDataBingding.TaskServiceReference;
using WpfDataBingding.DevTreeData;
using System.Collections.ObjectModel;
using WpfDataBingding.CustomDragDrop;


namespace WpfDataBingding.PageCollection.MonDevTaskPage
{
    /// <summary>
    /// MonDevTask_UC.xaml 的交互逻辑
    /// </summary>
    public partial class MonDevTask_UC : UserControl
    {
        DataBus dataBus;//监控代理列表（含设备集合）
        bus.DeviceType[] deviceTypeArray;//用于控件绑定的设备类型集合
           

        Point mousePosInButton;//全局保存鼠标相对设备图标按钮的坐标
        Point curPoint;//全局保存从左侧类型树中拖到显示面板的图标相对显示面板的坐标

        //拖曳鼠标位置暂存
        public Point CurPoint
        {
            get { return curPoint; }
            set { curPoint = value; }
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public MonDevTask_UC()
        {
            InitializeComponent();

            refresh_dataBus_deviceTypeArray();            
        }

        /// <summary>
        /// 在元素已布局、已呈现且可用于交互时发生的事件函数。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                bus.DeviceType[] deviceTypeArray = Application.Current.Properties["DeviceTypeArray"] as bus.DeviceType[];
                if (deviceTypeArray == null)
                    throw new ApplicationException("当前Application缓存查找不到设备类型类表");
                DevTypeCollection devTypeC = new DevTypeCollection();
                devTypeC.initFromDataBusDevTypeArray(deviceTypeArray);
                refreshTreeView(devTypeC);//初始化树拖曳功能

                this.initDropCanvas();//初始化显示面板:将该用户已经监控的设备的对应图标放置在面板上
            }
            catch (Exception e1)
            {
                MessageBox.Show(e1.Message);
            }
        }

        /// <summary>
        /// 从Application刷新成员dataBus和devTypeCollection
        /// </summary>
        void refresh_dataBus_deviceTypeArray()
        {
            string userID = Application.Current.Properties["userID"] as string;
            this.deviceTypeArray = Application.Current.Properties["DeviceTypeArray"] as bus.DeviceType[];
            this.dataBus = Application.Current.Properties["DataBus"] as DataBus;
        }

        /// <summary>
        /// 初始化显示面板:将该用户已经监控的设备的对应图标放置在面板上
        /// </summary>
        void initDropCanvas()
        {
            this.curPoint = new Point(5, 5);
            List<Device> devMonitedDevList= dataBus.getMonitedDevList();//获取已监控设备列表
            foreach (Device devMonited in devMonitedDevList)
            {                
                this.AddDevIconToDropPanel(devMonited);

                this.curPoint = new Point((curPoint.X + 50), curPoint.Y);
            }
        }

        /// <summary>
        /// 刷新所有数据
        /// </summary>
        public void refreshData()
        {
            string userID = Application.Current.Properties["userID"] as string;
            bus.DataBusServiceClient dataBusServiceClient = new bus.DataBusServiceClient();
            try
            {
                DataBus dataBus1 = new DataBus();
                dataBus1.fillDataBusByRemoteService(dataBusServiceClient,userID);
                //this.dataBus = dataBus1;
                Application.Current.Properties["DataBus"] = dataBus1;
                bus.DeviceType[] deviceTypeArray=dataBusServiceClient.QueryAllDeviceTypeInfo();
                Application.Current.Properties["DeviceTypeArray"] = deviceTypeArray;
                DevTypeCollection devTypeC=new DevTypeCollection();
                devTypeC.initFromDataBusDevTypeArray(deviceTypeArray);
                refreshTreeView(devTypeC);
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.Message);
                return;
            }
            finally
            {
                if (dataBusServiceClient != null)
                    dataBusServiceClient.Close();
                dataBusServiceClient = null;
            }
        }

        /// <summary>
        /// 刷新树控件
        /// </summary>
        void refreshTreeView(DevTypeCollection devTypeC)
        {
            treeView1.DataContext = devTypeC.DevTypeList;
            treeView1.ItemsSource = devTypeC.DevTypeList;

            wrapTreeViewItemForDrag(devTypeC);
        }

        /// <summary>
        /// 面板drop事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Panel_Drop(object sender, DragEventArgs e)
        {            
            if (DragData.Data != null)
            {
                Type controlType=DragData.Data.GetType();
                //拖动的控件为左侧设备类型图标树节点
                if (controlType == typeof(ContentPresenter))
                {
                    this.curPoint = e.GetPosition(drop_grid);//全局保存图标拖曳位置
                    //获取拖曳事件控件
                    ContentPresenter contentPresenter = DragData.Data as ContentPresenter;
                    //获取绑定到数据模板的数据对象
                    DevType _devType = contentPresenter.Content as DevType;
                    //根据设备类型和已监督设备集合获取配置窗口数据源
                    List<Device> typeDevList = this.dataBus.getCertainDevTypeList(_devType.TypeName);

                    ObservableCollection<Device> devsSource = new ObservableCollection<Device>();
                    foreach (Device dev in typeDevList)
                    {
                        if (dev.IsMonitered == false)
                            devsSource.Add(dev);
                    }

                    CreateDevConfigWin(devsSource);// 创建配置设备监控信息窗口                  
                }
                //拖动的为drop面板上的图标按钮
                else if (controlType == typeof(Button))
                {
                    Point dropPoint = e.GetPosition(drop_grid);//全局保存图标拖曳位置
                    Button button =DragData.Data as Button;//获取按钮实例      
                    //设置button在Canvas上的位置:注意鼠标相对图标位置的坐标误差
                    double pos_X = dropPoint.X - this.mousePosInButton.X;
                    double pos_Y = dropPoint.Y - this.mousePosInButton.Y;
                    if (dropPoint.X - this.mousePosInButton.X < 0)//X坐标超出下限
                        pos_X = 0;
                    else if (dropPoint.X + (button.Width - this.mousePosInButton.X) > this.drop_grid.Width)//X坐标超出上限
                        pos_X = this.drop_grid.Width - button.Width;
                    if (dropPoint.Y - this.mousePosInButton.Y < 0)//Y坐标超出下限
                        pos_Y = 0;
                    else if (dropPoint.Y + (button.Height - this.mousePosInButton.Y) > this.drop_grid.Height)//Y坐标超出上限
                        pos_Y = this.drop_grid.Height - button.Height;
                    Canvas.SetTop(button, pos_Y);
                    Canvas.SetLeft(button, pos_X);                    
                }
            }            
        }

        /// <summary>
        /// 设备类型树面板上的Drop事件：用于删除监控的设备
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_Drop(object sender, DragEventArgs e)
        {
            if (DragData.Data == null)
            {
                System.Diagnostics.Debug.WriteLine(true, "private void treeView1_Drop(object sender, DragEventArgs e):拖拽的控件对象为null");
                return;
            }
            Type controlType=DragData.Data.GetType();
            //拖动的控件为左侧设备类型图标树节点
            if (controlType == typeof(Button))
            {
                Button button = DragData.Data as Button;//获取按钮实例
                Device devS = button.DataContext as Device;
                if (devS == null)
                {
                    System.Diagnostics.Debug.WriteLine(true, "private void treeView1_Drop(object sender, DragEventArgs e):button未绑定设备对象数据源");
                    return;
                }
                //调用数据总线服务删除对该设备的监控                
                try
                {
                    MonTaskConfigration.deleteMonDevTask(devS);
                }
                catch (Exception exp)
                {
                    MessageBox.Show("移除对设备" + devS.DevID + "的监控操作失败：" + exp.Message);
                    return;
                }
                //界面上删除
                this.drop_grid.Children.Remove(button);
            }                
        }

        /// <summary>
        /// 向监控显示模版添加设备图标
        /// </summary>
        /// <param name="dataCell">设备源数据对象</param>
        public void AddDevIconToDropPanel(Device deviceS)
        {

            //向界面添加图标
            Button button = new Button();
            new CustomDragDropHelper(button);//设置为可拖曳
            button.DataContext = deviceS;//绑定数据源
            button.ToolTip = deviceS.Name;
            button.Click += new RoutedEventHandler(this.DevIconButton_Click);//添加处理函数
            //添加图标上鼠标左键按下事件：用于记录鼠标位置与图标左上角位置的相对距离
            button.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(this.DevIcon_button_PreviewMouseLeftButtonDown);
            button.Height = 40;//设置按钮尺寸
            button.Width = 40;
            Canvas.SetLeft(button,this.curPoint.X);//设置图标按钮位置
            Canvas.SetTop(button, this.curPoint.Y);

            Image image = new Image();
            try
            {
                //for debug---不知如何设置相对Uri来获取图标资源
                this.refresh_dataBus_deviceTypeArray();
                bus.DeviceType deviceType= MonTaskConfigration.getDeviceTypeByName(this.deviceTypeArray, deviceS.DevType);
                string iconFullName = DevType.IconPah + deviceType.DevTypeIconName;
                image.Source = new BitmapImage(new Uri(iconFullName));/////////debug
                image.Margin = new Thickness(0, 0, 0, 0);
                image.Stretch = Stretch.Fill;

                button.Content = image;
            }
            catch (Exception e1)
            {
                MessageBox.Show(e1.Message);
            }
            
            this.drop_grid.Children.Add(button);                        
        }

        /// <summary>
        /// 图标上鼠标左键按下事件：用于记录鼠标位置与图标左上角位置的相对距离
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void DevIcon_button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Button button = sender as Button;
            this.mousePosInButton = e.GetPosition(button);//全局保存鼠标相对设备图标按钮的坐标            
        }

        /// <summary>
        /// 点击设备图标按钮事件--查看设备监控状态
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DevIconButton_Click(object sender, RoutedEventArgs e)
        {
            Button buttonSender=(sender as Button);
            Device devS = buttonSender.DataContext as Device;//获取数据源
            // 创建显示设备监控详细信息窗口
            CreateDevDetailWin(devS);
        }

        /// <summary>
        /// 创建配置设备监控信息窗口
        /// </summary>
        private void CreateDevConfigWin(ObservableCollection<Device> devsSource)
        {
            AddDevMonWin addDevMonWin = new AddDevMonWin();
            addDevMonWin.Owner_UC = this;//设定窗口主从关系

            addDevMonWin.DataContext = devsSource;
            addDevMonWin.Show();
            //设父窗口不可用
            this.IsEnabled = false;
        }

        /// <summary>
        /// 创建显示设备监控详细信息窗口
        /// </summary>
        private void CreateDevDetailWin(Device devS)
        {
            MessageBox.Show("设备" + devS.DevID + "监控详细信息");
        }
        
        /// <summary>
        /// 将新的数据对象集合对应的TreeViewItem控件包装为可拖曳
        /// </summary>
        void wrapTreeViewItemForDrag(DevTypeCollection devCollection)
        {
            foreach (DevType dataCell in devCollection.DevTypeList)
            {
                //根据数据源对象获取UI控件
                TreeViewItem tvItem = treeView1.ItemContainerGenerator.ContainerFromItem(dataCell) as TreeViewItem;
                if (tvItem != null)
                {
                    new CustomDragDropHelper(tvItem);//包装成可拖曳的控件
                    //tvItem.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(tvItem_PreviewMouseLeftButtonDown);
                }
            }
        }

        /// <summary>
        /// 刷新后台所有数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void refreshButton_Click(object sender, RoutedEventArgs e)
        {
            refreshData();
        }



        /// <summary>
        /// 树节点图标上鼠标左键按下事件：用于记录鼠标位置与图标左上角位置的相对距离
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        //void tvItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        //{
        //    TreeViewItem TVItem = sender as TreeViewItem;            
        //}


    }
    
}
